package com.yxsk.relay.job.admin.web.controller;

import com.yxsk.relay.job.admin.data.entity.BaseEntity;
import com.yxsk.relay.job.admin.utils.IdUtils;
import com.yxsk.relay.job.admin.web.common.enums.ResultEnum;
import com.yxsk.relay.job.admin.web.common.exception.RelayAdminWebRuntimeException;
import com.yxsk.relay.job.admin.web.common.utils.EncryptUtil;
import com.yxsk.relay.job.admin.web.common.utils.EntityBeanUtil;
import com.yxsk.relay.job.admin.web.controller.valid.UserValid;
import com.yxsk.relay.job.admin.web.entity.User;
import com.yxsk.relay.job.admin.web.service.UserService;
import com.yxsk.relay.job.component.common.protocol.message.base.ResultResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;

/**
 * @author 小懒虫
 * @date 2018/8/14
 */
@Controller
@RequestMapping("/system/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 列表页面
     */
    @GetMapping("/index")
    public String index(Model model, User user) {
// 创建匹配器，进行动态查询匹配
        ExampleMatcher matcher = ExampleMatcher.matching().
                withMatcher("title", match -> match.contains());

        user.setDelFlag(BaseEntity.DelFlagEnum.NORMAL.getFlag());

        // 获取角色列表
        Example<User> example = Example.of(user, matcher);
        // 获取用户列表
        Page<User> list = userService.getPageList(example);

        // 封装数据
        model.addAttribute("list", list.getContent());
        model.addAttribute("page", list);
        return "/system/user/index";
    }

    /**
     * 跳转到添加页面
     */
    @GetMapping("/add")
    public String toAdd() {
        return "/system/user/add";
    }

    /**
     * 跳转到编辑页面
     */
    @GetMapping("/edit/{id}")
    public String toEdit(@PathVariable("id") User user, Model model) {
        model.addAttribute("user", user);
        return "/system/user/add";
    }

    /**
     * 保存添加/修改的数据
     *
     * @param valid 验证对象
     * @param user  实体对象
     */
    @PostMapping("/save")
    @ResponseBody
    public ResultResponse save(@Validated UserValid valid, User user) {

        // 验证数据是否合格
        if (user.getId() == null) {

            // 判断密码是否为空
            if (user.getPassword().isEmpty() || "".equals(user.getPassword().trim())) {
                throw new RelayAdminWebRuntimeException(ResultEnum.USER_PWD_NULL);
            }

            // 判断两次密码是否一致
            if (!user.getPassword().equals(valid.getConfirm())) {
                throw new RelayAdminWebRuntimeException(ResultEnum.USER_INEQUALITY);
            }

            // 对密码进行加密
            String salt = UUID.randomUUID().toString().replace("-", "").substring(0, 15);
            String encrypt = EncryptUtil.encrypt(user.getPassword(), salt);
            user.setPassword(encrypt);
            user.setSalt(salt);
        }

        // 判断用户名是否重复
        if (userService.repeatByUsername(user)) {
            throw new RelayAdminWebRuntimeException(ResultEnum.USER_EXIST);
        }

        // 复制保留无需修改的数据
        if (user.getId() != null) {
            // 不允许操作超级管理员数据
            if ("1".equals(user.getId())) {
                throw new RelayAdminWebRuntimeException(ResultEnum.NO_ADMIN_AUTH);
            }

            User beUser = userService.findById(user.getId());
            String[] fields = {"password", "salt", "picture", "roles"};
            EntityBeanUtil.copyProperties(beUser, user, fields);
        }

        if (!StringUtils.hasLength(user.getId())) {
            user.setId(IdUtils.nextId());
        }

        // 保存数据
        userService.addEntity(user);
        return ResultResponse.ok("保存成功");
    }

    /**
     * 跳转到详细页面
     */
    @GetMapping("/detail/{id}")
    public String toDetail(@PathVariable("id") User user, Model model) {
        model.addAttribute("user", user);
        return "/system/user/detail";
    }

    /**
     * 跳转到修改密码页面
     */
    @GetMapping("/pwd")
    public String toEditPassword(Model model, @RequestParam(value = "ids", required = false) List<String> ids) {
        model.addAttribute("idList", ids);
        return "/system/user/pwd";
    }

    /**
     * 修改密码
     */
    @PostMapping("/pwd")
    @ResponseBody
    public ResultResponse editPassword(String password, String confirm,
                                       @RequestParam(value = "ids", required = false) List<String> ids,
                                       @RequestParam(value = "ids", required = false) List<User> users) {

        // 判断密码是否为空
        if (password.isEmpty() || "".equals(password.trim())) {
            throw new RelayAdminWebRuntimeException(ResultEnum.USER_PWD_NULL);
        }

        // 判断两次密码是否一致
        if (!password.equals(confirm)) {
            throw new RelayAdminWebRuntimeException(ResultEnum.USER_INEQUALITY);
        }

        // 不允许操作超级管理员数据
        if (ids.contains("1")) {
            throw new RelayAdminWebRuntimeException(ResultEnum.NO_ADMIN_AUTH);
        }

        // 修改密码，对密码进行加密
        users.forEach(user -> {
            String salt = UUID.randomUUID().toString().replace("-", "").substring(0, 15);
            String encrypt = EncryptUtil.encrypt(password, salt);
            user.setPassword(encrypt);
            user.setSalt(salt);
        });

        // 保存数据
        userService.addEntities(users);
        return ResultResponse.ok("修改成功");
    }

    @GetMapping("/status/delete")
    @ResponseBody
    public ResultResponse delete(String ids) {
        if (StringUtils.isEmpty(ids)) {
            return ResultResponse.ok("未选择删除用户");
        }
        String[] userIds = ids.split(",");
        Stream.of(userIds).forEach(id -> this.userService.deleteById(id));
        return ResultResponse.ok("删除成功");
    }

}
